#include "StdAfx.h"
#include "AIController.h"


AIController::AIController(AIControlLogic *logic)
{

	controlLogic = logic;

}


AIController::~AIController(void)
{
}

bool AIController::apply(EntityControl* entity,const ControlContext& context)
{

	AIEntityControlStub entityStub = AIEntityControlStub(entity);
	//std::vector<Trigger*> satisfiedTriggers = std::vector<Trigger*>();


	for(int i = 0; i < controlLogic->getGoalList()->at(0)->getTriggerList()->size(); i++)
	{
		Trigger * trigger = new Trigger();
		//*********************************************************************************
		//TODO This uses only the first goal
		//*********************************************************************************
		trigger = (controlLogic->getGoalList()->at(0)->getTriggerList()->at(i));
		trigger->setAllReqDirty(true);
		entityStub.AddTrigger(trigger);

		//if(trigger->CheckReq(&((EntityControl)entityStub)))
		//{
		//	satisfiedTriggers.push_back(trigger);
		//}

	}
	std::vector<Trigger*> * satisfiedTriggers = entityStub.checkSatisfiedTriggers();
	Ogre::LogManager::getSingleton().logMessage(" ");
	Ogre::LogManager::getSingleton().logMessage("Size of satisfied triggers "+Ogre::StringConverter::toString(satisfiedTriggers->size()));

	if(entityStub.isParameterFilled("target"))
	{
		entity->setParameter("target", entityStub.getParameter("target"));
	}

	if(satisfiedTriggers->size()>0)
	{

		int minResult = INT_MAX;
		Trigger * bestMove;

		

		for(int i=0; i< satisfiedTriggers->size(); i++)
		{
			


			AIEntityControlStub newEntityStub = AIEntityControlStub(entityStub);

			newEntityStub.fireTrigger(satisfiedTriggers->at(i));
			int result = builAITree(&newEntityStub,1);
			Ogre::LogManager::getSingleton().logMessage("Final results "+Ogre::StringConverter::toString(result));
			if(result<minResult)
			{
				bestMove = satisfiedTriggers->at(i);
				minResult = result;
			}

		}
		Ogre::LogManager::getSingleton().logMessage("FINAL minimal result "+Ogre::StringConverter::toString(minResult));
		Ogre::LogManager::getSingleton().logMessage("**********************************************************************");
		bestMove->FireTrigger(entity);
	}


	return true;

}

int AIController::builAITree(AIEntityControlStub * entity, int depth)
{
	int currentValue=  controlLogic->getGoalList()->at(0)->calcGoalValue(entity);

	if(depth>=5)
	{
		return currentValue;
	}
	depth++;

	std::vector<Trigger*> *satisfiedTriggers = entity->checkSatisfiedTriggers();

	Ogre::LogManager::getSingleton().logMessage("	 Size of satisfied triggers "+Ogre::StringConverter::toString(satisfiedTriggers->size()));

	int sum = currentValue;
	int resultCount = 0;


	if(satisfiedTriggers->size()>0)
	{


		for(int i=0; i< satisfiedTriggers->size(); i++)
		{
			AIEntityControlStub newEntityStub = AIEntityControlStub(entity);

			newEntityStub.fireTrigger(satisfiedTriggers->at(i));
			int newValue = controlLogic->getGoalList()->at(0)->calcGoalValue(&newEntityStub);
			int result = newValue;
			if(newValue<sum)
			{
				double diffRate = (double)newValue/(double)sum;
				diffRate/=4.0;
				diffRate*=100.0;
				diffRate=100.0-diffRate;
				if(rand()%100<diffRate)
				{
					result = builAITree(&newEntityStub,depth);
				}
			}
			else
			{
				double diffRate =(double)sum/(double)newValue;
				diffRate/=10.0;
				diffRate*=100.0;
				if(rand()%100<diffRate)
				{
					result = builAITree(&newEntityStub,depth);
				}

			}
			Ogre::LogManager::getSingleton().logMessage("	 "+Ogre::StringConverter::toString(depth-1)+". result "+Ogre::StringConverter::toString(result));
			if(sum > result)
			{
				sum=result;
			}
			resultCount++;
		}

		//Ogre::LogManager::getSingleton().logMessage("	 Calculated return sum "+Ogre::StringConverter::toString((controlLogic->getGoalList()->at(0)->calcGoalValue(entity) + (sum/resultCount))/2));
		Ogre::LogManager::getSingleton().logMessage("	 Calculated return sum "+Ogre::StringConverter::toString(sum));


		//return (controlLogic->getGoalList()->at(0)->calcGoalValue(entity) + (sum/resultCount))/2;
		return sum;
	}

	else
	{
		Ogre::LogManager::getSingleton().logMessage("	 Return value (no sat) "+Ogre::StringConverter::toString(controlLogic->getGoalList()->at(0)->calcGoalValue(entity)));

		return controlLogic->getGoalList()->at(0)->calcGoalValue(entity);
	}

	


}




bool AIController::isSpawningNeeded()
{
	return false;
}

Controller::Projectile AIController::getNextSpawnItem()
{
	return Projectile();

}
